﻿using DzInfo.Model.HS;
using DzInfo.Model.KD;
using Kingdee.BOS;
using Kingdee.BOS.App.Core;
using Kingdee.BOS.App.Data;
using Kingdee.BOS.Contracts;
using Kingdee.BOS.Core;
using Kingdee.BOS.Core.Bill;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Core.Metadata.ConvertElement.PlugIn;
using Kingdee.BOS.Core.Metadata.ConvertElement.PlugIn.Args;
using Kingdee.BOS.Core.Metadata.FieldElement;
using Kingdee.BOS.Core.Metadata.FormElement;
using Kingdee.BOS.Core.SqlBuilder;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.ServiceHelper;
using Kingdee.BOS.Util;
using Newtonsoft.Json;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Information;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DzInfo.DzSchedule.HS
{
    [Description("HS：下推API扩展"), HotUpdate]
    public class HsAfterConvert : AbstractConvertPlugIn
    {
        public override void AfterConvert(AfterConvertEventArgs e)
        {
            if (this.Context.ServiceType != WebType.WebService)
            {
                return;
            }
            if (!base.Option.GetVariables().ContainsKey("HSParamters"))
            {
                return;
            }
            //单据体ORM标识
            AfterConvertOrm orm = new AfterConvertOrm();
            SetOrm(e.SourceBusinessInfo.GetForm().Id, e.TargetBusinessInfo.GetForm().Id, orm);
            ExtendedDataEntity[] array = e.Result.FindByEntityKey("FBillHead");
            IBillView billView = CreateBillView(e.TargetBusinessInfo.GetForm().Id);
            var json = base.Option.GetVariables()["HSParamters"].GetString();
            //Dictionary<string, List<object>> dictionary = base.Option.GetVariables()["HSParamters"] as Dictionary<string, List<object>>;
            ExtendedDataEntity[] array2 = array;
            for (int i = 0; i < array2.Length; i++)
            {
                ExtendedDataEntity extendedDataEntity = array2[i];
                billView.Model.DataObject = extendedDataEntity.DataEntity;
                if (e.TargetBusinessInfo.GetForm().Id == "PRD_INSTOCK")
                {
                    var stockerId = base.Option.GetVariables()["FSTOCKERID"];
                    billView.Model.SetItemValueByID("FSTOCKERID", stockerId, 0);
                }
                RelatedFlexGroupField stockLocField = billView.BusinessInfo.GetField(orm.locStr) as RelatedFlexGroupField;
                if (!stockLocField.IsNullOrEmptyOrWhiteSpace())
                {
                    stockLocField.FlexDisplayFormat = FlexType.Format.FIXEDCOLUMN;
                }
                DynamicObjectCollection rows = billView.Model.DataObject[orm.entOrm] as DynamicObjectCollection;
                for (int j = 0; j < rows.Count; j++)
                {
                    var scrObj = rows[j][orm.linkStr] as DynamicObjectCollection;
                    string scrId = scrObj[0]["SId"].GetString();
                    //var dic = dictionary.Values;
                    List<HSParameter> customParams = JsonConvert.DeserializeObject<List<HSParameter>>(json);
                    foreach (var param in customParams)
                    {

                        var qty = param.Qty; //dic["qty"];
                        var stock = param.Stock;// dic["stock"].ToString();
                        var lot = param.Lot;// dic["lot"];
                        var loc = param.Loc;// dic["loc"].ToString();
                        string[] locs = loc.Split('.');
                        string fentryid = param.FEntryId;
                        if (fentryid == scrId)
                        {
                            DynamicObjectCollection cangWeiZhiJi = GetCangWeiZhiJi("BD_FLEXVALUES", locs);
                            billView.Model.SetValue(orm.qtyStr, qty, j);
                            billView.InvokeFieldUpdateService(orm.qtyStr, j);
                            billView.Model.SetItemValueByNumber(orm.stockStr, stock, j);
                            billView.Model.SetValue(orm.lotStr, lot, j);
                            billView.Model.SetItemValueByNumber(orm.locStr, loc, j);
                            if (!cangWeiZhiJi.IsNullOrEmptyOrWhiteSpace())
                            {
                                DynamicObject dyRow = billView.Model.GetEntityDataObject(stockLocField.Entity)[j];
                                // 清空仓位
                                stockLocField.DynamicProperty.SetValue(dyRow, null);
                                stockLocField.RefIDDynamicProperty.SetValue(dyRow, 0);
                                long hj = Convert.ToInt64(cangWeiZhiJi[0]["HJ"]);
                                long bai = Convert.ToInt64(cangWeiZhiJi[0]["BAI"]);
                                long lie = Convert.ToInt64(cangWeiZhiJi[0]["LIE"]);
                                long locId = GetLocId(hj, bai, lie);
                                if (locId <= 0)
                                {
                                    Dictionary<string, long> dctFlexItemIds = new Dictionary<string, long>();
                                    dctFlexItemIds.Add("FF100001", Convert.ToInt64(cangWeiZhiJi[0]["HJ"])); // 仓位值集Key - 仓位值内码
                                    dctFlexItemIds.Add("FF100002", Convert.ToInt64(cangWeiZhiJi[0]["BAI"])); // 仓位值集Key - 仓位值内码
                                    dctFlexItemIds.Add("FF100003", Convert.ToInt64(cangWeiZhiJi[0]["LIE"])); // 仓位值集Key - 仓位值内码
                                                                                                             // 新建仓位值属性数据包，用来存储各维度值
                                    DynamicObject stockLocObj = new DynamicObject(stockLocField.RefFormDynamicObjectType);
                                    foreach (var flexItem in dctFlexItemIds)
                                    {
                                        Field fldFlex = stockLocField.RelateFlexBusinessInfo.GetField(flexItem.Key);
                                        BaseDataField fldBDTypeFlex = fldFlex as BaseDataField;
                                        IViewService viewService = Kingdee.BOS.Contracts.ServiceFactory.GetService<IViewService>(this.Context);
                                        DynamicObject[] flexItemObjs = viewService.LoadFromCache(this.Context, new object[] { flexItem.Value }, fldBDTypeFlex.RefFormDynamicObjectType);

                                        fldBDTypeFlex.RefIDDynamicProperty.SetValue(stockLocObj, flexItem.Value);
                                        fldBDTypeFlex.DynamicProperty.SetValue(stockLocObj, flexItemObjs[0]);
                                    }
                                    stockLocField.DynamicProperty.SetValue(dyRow, stockLocObj);
                                    var obj = SaveFlexObject(this.Context, stockLocObj);
                                    long flexDataId = Convert.ToInt64(obj[0]);
                                    //stockLocField.RefIDDynamicProperty.SetValue(dyRow, flexDataId);
                                    stockLocField.DynamicProperty.SetValue(dyRow, obj);
                                    stockLocField.RefIDDynamicProperty.SetValue(dyRow, flexDataId);
                                }
                                else
                                {
                                    var stockLoc = BusinessDataServiceHelper.LoadFromCache(billView.Context, new object[] { locId }, stockLocField.RefFormDynamicObjectType);
                                    stockLocField.DynamicProperty.SetValue(dyRow, stockLoc[0]);
                                    stockLocField.RefIDDynamicProperty.SetValue(dyRow, locId);
                                }
                            }
                        }
                    }
                }
            }
        }

        private long GetLocId(long hj, long bai, long lie)
        {
            long locId = 0;
            string sql = "";
            sql = string.Format(@"/*dialect*/ 
            SELECT FID FROM T_BAS_FLEXVALUESDETAIL WHERE FF100001={0} AND FF100002={1} AND FF100003={2} ", hj, bai, lie);
            DynamicObjectCollection doc = DBUtils.ExecuteDynamicObject(this.Context, sql);
            if (doc.Count > 0)
            {
                locId = Convert.ToInt64(doc[0][0]);
            }
            return locId;
        }

        private static DynamicObject SaveFlexObject(Context ctx, DynamicObject flexData)
        {
            var seqReader = new SequenceReader(ctx);
            var businessDataService = new BusinessDataService();
            seqReader.AutoSetPrimaryKey(new[] { flexData }, flexData.DynamicObjectType);
            return businessDataService.Save(ctx, new[] { flexData })[0];

        }

        private DynamicObjectCollection GetCangWeiZhiJi(string formId, string[] fnumber)
        {
            if (fnumber.Length == 1 && fnumber[0].IsNullOrEmptyOrWhiteSpace()) { return null; }
            var loc1 = fnumber[0];
            var loc2 = fnumber[1];
            var loc3 = fnumber[2];
            var loc4 = fnumber[3];
            var loc5 = fnumber[4];
            var loc6 = fnumber[5];
            string sql = "";
            sql = string.Format(@"/*dialect*/ 
            SELECT T0.FENTRYID HJ,T1.FENTRYID BAI,T2.FENTRYID LIE 
            FROM (
            SELECT T1.FENTRYID FROM T_BAS_FLEXVALUES T0
            JOIN T_BAS_FLEXVALUESENTRY  T1 ON T1.FID=T0.FID
            WHERE T0.FNUMBER='{0}' AND T1.FNUMBER='{1}' 
            ) T0
            LEFT JOIN (
            SELECT T1.FENTRYID FROM T_BAS_FLEXVALUES T0
            JOIN T_BAS_FLEXVALUESENTRY  T1 ON T1.FID=T0.FID
            WHERE T0.FNUMBER='{2}' AND T1.FNUMBER='{3}' 
            ) T1 ON 1=1
            LEFT JOIN (
            SELECT T1.FENTRYID FROM T_BAS_FLEXVALUES T0
            JOIN T_BAS_FLEXVALUESENTRY  T1 ON T1.FID=T0.FID
            WHERE T0.FNUMBER='{4}' AND T1.FNUMBER='{5}' 
            ) T2 ON 1=1 ", loc1, loc2, loc3, loc4, loc5, loc6);
            DynamicObjectCollection doc = DBUtils.ExecuteDynamicObject(this.Context, sql);
            if (doc.Count > 0)
            {
                return doc;
            }
            return null;
        }

        private void SetOrm(string id1, string id2, AfterConvertOrm orm)
        {
            //发货通知单>销售出库单
            if (id2 == "SAL_OUTSTOCK")
            {
                orm.linkStr = "FEntity_Link";
                orm.entOrm = "SAL_OUTSTOCKENTRY";
                orm.qtyStr = "FRealQty";
                orm.stockStr = "FStockID";
                orm.lotStr = "FLot";
                orm.locStr = "FStockLocID";
            }
            //退货通知单>销售退货单
            if (id2 == "SAL_RETURNSTOCK")
            {
                orm.linkStr = "FEntity_Link";
                orm.entOrm = "SAL_RETURNSTOCKENTRY";
                orm.qtyStr = "FRealQty";
                orm.stockStr = "FStockId";
                orm.lotStr = "FLot";
                orm.locStr = "FStocklocId";
            }
            //收料通知单>采购入库单
            if (id2 == "STK_InStock")
            {
                orm.linkStr = "FInStockEntry_Link";
                orm.entOrm = "InStockEntry";
                orm.qtyStr = "FRealQty";
                orm.stockStr = "FStockId";
                orm.lotStr = "FLot";
                orm.locStr = "FStockLocId";
            }
            //调拨申请单>直接调拨单
            if (id2 == "STK_TransferDirect")
            {
                orm.linkStr = "FBillEntry_Link";
                orm.entOrm = "TransferDirectEntry";
                orm.qtyStr = "FQty";
                orm.stockStr = "FDestStockId";
                orm.lotStr = "FDestLot";
                orm.locStr = "FDestStockLocId";
            }
            //生产订单>生产入库单
            if (id2 == "PRD_INSTOCK")
            {
                orm.linkStr = "FEntity_Link";
                orm.entOrm = "Entity";
                orm.qtyStr = "FRealQty";
                orm.stockStr = "FStockId";
                orm.lotStr = "FLot";
                orm.locStr = "FStockLocId";
            }
            //生产订单>生产领料单
            if (id2 == "PRD_PickMtrl")
            {
                orm.linkStr = "FEntity_Link";
                orm.entOrm = "Entity";
                orm.qtyStr = "FActualQty";
                orm.stockStr = "FStockId";
                orm.lotStr = "FLot";
                orm.locStr = "FStockLocId";
            }
        }

        private IBillView CreateBillView(string formId)
        {
            FormMetadata formMetadata = MetaDataServiceHelper.Load(base.Context, formId) as FormMetadata;
            Form form = formMetadata.BusinessInfo.GetForm();
            Type type = Type.GetType("Kingdee.BOS.Web.Import.ImportBillView,Kingdee.BOS.Web");
            IDynamicFormViewService dynamicFormViewService = (IDynamicFormViewService)Activator.CreateInstance(type);
            BillOpenParameter param = CreateOpenParameter(formMetadata);
            IResourceServiceProvider formServiceProvider = form.GetFormServiceProvider();
            dynamicFormViewService.Initialize(param, formServiceProvider);
            return dynamicFormViewService as IBillView;
        }

        private BillOpenParameter CreateOpenParameter(FormMetadata meta)
        {
            Form form = meta.BusinessInfo.GetForm();
            BillOpenParameter billOpenParameter = new BillOpenParameter(form.Id, meta.GetLayoutInfo().Id);
            billOpenParameter.Context = base.Context;
            billOpenParameter.ServiceName = form.FormServiceName;
            billOpenParameter.PageId = Guid.NewGuid().ToString();
            billOpenParameter.FormMetaData = meta;
            billOpenParameter.Status = OperationStatus.ADDNEW;
            billOpenParameter.PkValue = null;
            billOpenParameter.CreateFrom = CreateFrom.Default;
            billOpenParameter.GroupId = "";
            billOpenParameter.ParentId = 0;
            billOpenParameter.DefaultBillTypeId = "";
            billOpenParameter.DefaultBusinessFlowId = "";
            billOpenParameter.SetCustomParameter("ShowConfirmDialogWhenChangeOrg", false);
            List<AbstractDynamicFormPlugIn> list = form.CreateFormPlugIns();
            billOpenParameter.SetCustomParameter(FormConst.PlugIns, list);
            PreOpenFormEventArgs preOpenFormEventArgs = new PreOpenFormEventArgs(base.Context, billOpenParameter);
            foreach (AbstractDynamicFormPlugIn item in list)
            {
                item.PreOpenForm(preOpenFormEventArgs);
            }
            if (preOpenFormEventArgs.Cancel)
            {
            }
            return billOpenParameter;
        }
    }
}
